---
title: "How Empathy and Partisanship Affected Attitude Changes Following the Assassination of Shinzo Abe: Evidence from Panel Surveys"
output:
  html_document:
    df_print: paged
    toc: true
    toc_float: 
      collapsed: false
      smooth_scroll: true
    toc_depth: 3
    number_sections: true
    code_folding: hide
    highlight: tango
    fig_width: 10
    fig_height: 6
    dpi: 300
---

# Setup

```{r, setup, message=FALSE, warning=FALSE}

# Set global chunk options
knitr::opts_chunk$set(
  echo = TRUE,
  warning = FALSE,
  message = FALSE,
  fig.width = 10,
  fig.height = 6,
  dpi = 300
)

# Check and install missing packages
required_packages <- c("tidyverse", "haven", "readr", "dplyr", "plm", 
                      "stargazer", "ggplot2", "ggpubr", "gridExtra", 
                      "ggthemes", "grid", "scales",'kableExtra','DT','modelsummary')

missing_packages <- required_packages[!required_packages %in% installed.packages()[,"Package"]]

if(length(missing_packages) > 0) {
  cat("Installing missing packages:", paste(missing_packages, collapse = ", "), "\n")
  install.packages(missing_packages)
}

# Load required packages
library(tidyverse)
library(haven)
library(readr)
library(dplyr)
library(plm)
library(stargazer)
library(ggplot2)
library(ggpubr)
library(gridExtra)
library(ggthemes)
library(grid)
library(scales)
library(kableExtra)
library(DT)
library(modelsummary)

# Custom theme function
theme_Publication <- function(base_size=14) {
      (theme_foundation(base_size=base_size)
       + theme(plot.title = element_text(face = "bold",
                                         size = rel(1.2), hjust = 0.5),
               text = element_text(),
               panel.background = element_rect(colour = NA),
               plot.background = element_rect(colour = NA),
               panel.border = element_rect(colour = NA),
               axis.title = element_text(face = "bold",size = rel(1)),
               axis.title.y = element_text(angle=90,vjust =2),
               axis.title.x = element_text(vjust = -0.2),
               axis.text = element_text(), 
               axis.line = element_line(colour="black"),
               axis.ticks = element_line(),
               panel.grid.major = element_line(colour="#f0f0f0"),
               panel.grid.minor = element_blank(),
               legend.key = element_rect(colour = NA),
               legend.position = "bottom",
               legend.direction = "horizontal",
               legend.key.size= unit(0.2, "cm"),
               legend.margin = unit(0, "cm"),
               legend.title = element_text(face="italic"),
               plot.margin=unit(c(10,5,5,5),"mm"),
               strip.background=element_rect(colour="#f0f0f0",fill="#f0f0f0"),
               strip.text = element_text(face="bold")
          ))
}

# Custom color scale functions
scale_fill_Publication <- function(...){
      pub_colors <- c("#386cb0","#fdb462","#7fc97f","#ef3b2c","#662506",
                      "#a6cee3","#fb9a99","#984ea3","#ffff33")
      discrete_scale("fill","Publication",manual_pal(values = pub_colors), ...)
}

scale_colour_Publication <- function(...){
      pub_colors <- c("#386cb0","#fdb462","#7fc97f","#ef3b2c","#662506",
                      "#a6cee3","#fb9a99","#984ea3","#ffff33")
      discrete_scale("colour","Publication",manual_pal(values = pub_colors), ...)
}

# Significance stars function
star_function <- function(p_value) {
  if (p_value < 0.001) return("***")
  else if (p_value < 0.01) return("**")
  else if (p_value < 0.05) return("*")
  else return("")
}

cat("Setup completed!\n")
```
# Load Data

- ```abe_rating```: Attitudes toward Abe (0-10 scale, higher values indicate more favorable attitudes)
- ```abe_attitude_change```: Change in attitudes toward Abe between pre- and post-assassination period (post - pre: higher values indicate more positive change)
- ```age```: Age of the respondent in the first wave survey
- ```female```: 1 indicates female and 0 indicates male
- ```edu```: Education level (1: Primary School, 2:High School, 3: Vocational School, 4: Junior College, 5: Bachelor, 6:Graduate School)
- ```b_sympathetic```:Empathy of the respondent (1-7 scale, higher values indicate a higher level of empathy)
- ```pid_before```: Partisanship of individuals before the assassination
- ```pid_change_before```: The number of supported party answered in surveys before the assassination

```{r data-loading}
# Data loading with validation
if (!file.exists("data.csv")) {
  stop("Error: data.csv file does not exist, please check the file path")
}
panel <- read_csv("data.csv")

panel <- pdata.frame(panel, index = c("id", "time"))

# Factor variable processing with proper ordering
panel$pid_before <- factor(
  panel$pid_before,
  levels = c("No Support", "No Answer", "Other", "LDP", "CDP",
             "DPP", "Komei", "JCP", "JIP", "Reiwa")
)

cat("\n**Data Overview:**\n")

datatable(
  panel %>% head(10),
  options = list(scrollX = TRUE)  # 横向滚动条
)
```

# Analysis

## Figure 1-A
```{r figure1a, fig.cap="Attitudes toward Abe before and after the assassination"}
attitude_change<-panel[,c("id","time","abe_rating")]

# Summarize the data
df_summary <- attitude_change %>%
  group_by(time) %>%
  summarise(
    n = n(),
    mean_value = mean(abe_rating, na.rm = TRUE),
    sd_value = sd(abe_rating, na.rm = TRUE),
    se_value = sd_value / sqrt(n),
    ci_lower = mean_value - qt(0.975, df = n - 1) * se_value,
    ci_upper = mean_value + qt(0.975, df = n - 1) * se_value,
    .groups = "drop"
  )

# Statistical testing
t_test_result <- t.test(abe_rating ~ time, data = attitude_change)
significance_stars <- star_function(t_test_result$p.value)

p_value_display <- sprintf("%.3e", t_test_result$p.value)
  # Calculate mean differences for specific times
mean_pre <- mean(attitude_change[["abe_rating"]][attitude_change$time == "Pre-assassination"], na.rm = TRUE)
mean_post <- mean(attitude_change[["abe_rating"]][attitude_change$time == "Post-assassination"], na.rm = TRUE)
mean_difference <- mean_post - mean_pre

df_summary$time <- factor(df_summary$time, levels = c("Pre-assassination", "Post-assassination"))
  
# Create the plot
attitude_abe_p <- ggplot(df_summary, aes(x = time, y = mean_value, group = "abe_rating")) +
    geom_point() +
    geom_line(linetype = 2) +
    geom_pointrange(aes(ymin = ci_lower, ymax = ci_upper)) +  # Use 95% CI
    ylim(3.5, 5.5) +
    xlab("") +
    ylab("Attitudes toward Abe") +
    labs(
      subtitle = paste(
        "Mean Difference: ", round(mean_difference, 3), " ", significance_stars, "\n",
        "p<0.001 "
      )
    ) +
    theme_Publication() +
    theme(
      plot.subtitle = element_text(hjust = 0.5)  # Center the subtitle
    )

attitude_abe_p
```

## Figure 1-B

```{r figure1b, fig.cap="Changes in attitude toward Abe compared to respondents’ attitudes toward Abe before the assassination. "}

# Check if required variables exist, if not create them
if (!"post" %in% names(panel)) {
  panel$post <- as.numeric(panel$time == "Post-assassination")
}

if (!"abe_attitude_change" %in% names(panel)) {
  # Calculate attitude change
  attitude_wide <- panel %>%
    select(id, time, abe_rating) %>%
    pivot_wider(names_from = time, values_from = abe_rating) %>%
    mutate(abe_attitude_change = `Post-assassination` - `Pre-assassination`)
  
  panel <- panel %>%
    left_join(attitude_wide %>% select(id, abe_attitude_change), by = "id")
}

# Prepare data for plotting
attitude_change_by_group <- panel %>%
  filter(post == 0) %>%
  group_by(abe_rating) %>%
  summarise(
    mean_attitude_change = mean(abe_attitude_change, na.rm = TRUE),
    se_attitude_change   = sd(abe_attitude_change, na.rm = TRUE) / sqrt(n()),
    n = n(),
    .groups = "drop"
  ) %>%
  mutate(abe_rating = factor(abe_rating, levels = sort(unique(abe_rating))))

# Plot
fig1_b <- ggplot(attitude_change_by_group, 
                 aes(x = abe_rating, y = mean_attitude_change, fill = mean_attitude_change)) + 
  geom_col(width = 0.7) +  # clearer than geom_bar(stat = "identity")
  geom_errorbar(
    aes(ymin = mean_attitude_change - se_attitude_change, 
        ymax = mean_attitude_change + se_attitude_change),
    width = 0.2, linewidth = 0.6
  ) +
  scale_fill_gradient2(
    low = "#ef3b2c",    # red for negative values
    mid = "gray90",     # light gray around 0
    high = "#386cb0",   # blue for positive values
    midpoint = 0
  ) +
  labs(
    x = "Attitudes toward Abe during Pre-assassination Period",
    y = "Change in Attitudes") +
  theme_Publication() +
  theme(
    legend.position = "none",
    axis.text.x = element_text(size = 12),
    axis.text.y = element_text(size = 12),
    plot.title = element_text(hjust = 0.5, size = 14)
  )

# Display
fig1_b
```


## Table 1

```{r table1, results='asis'}
# Ensure post variable exists
if (!"post" %in% names(panel)) {
  panel$post <- as.numeric(panel$time == "Post-assassination")
}

# Model estimation
tryCatch({
  model1 <- plm(abe_rating ~ post, data = panel, model = "within")
  model2 <- plm(abe_rating ~ post * b_sympathetic, data = panel, model = "within")
  model3 <- plm(abe_rating ~ post * pid_before, data = panel, model = "within")
  model4 <- plm(abe_rating ~ post * pid_change_before, data = panel, model = "within")
  model5 <- plm(abe_rating ~ post * b_sympathetic + post * pid_before + post * pid_change_before, 
                data = panel, model = "within")
  
  # HTML version for better web display
  stargazer(model1, model2, model3, model4, model5,
            type = "html", # change the type to text for console output
            covariate.labels = c(
              "Post-assassination",
              "Post × Empathy", 
              "Post × No Answer",
              "Post × Other Party",
              "Post × LDP",
              "Post × CDP",
              "Post × DPP", 
              "Post × Komei",
              "Post × JCP",
              "Post × JIP",
              "Post × Reiwa",
              "Post × Partisanship Strength"
            ),
            column.labels = c("Base Model", "Empathy", "Party ID", "Party Support", "Full Model"),
            dep.var.labels = "Attitudes toward Abe",
            table.layout = "=dc#-t-a-s-n")
})
```

